import { useState, useEffect, useCallback } from 'react';
import {
  Modal, message, DatePicker, Tree, Button, Spin, Input, InputNumber, TreeProps
} from 'antd';
import {
  LeftOutlined, RightOutlined, PlusOutlined,
  DownOutlined, UpOutlined
} from '@ant-design/icons';
import dayjs, { Dayjs } from 'dayjs';
import { task_list, studentList, task_add } from '@/api/clock';
import './module.css/module.clock.css';

// 任务类型定义
interface Task {
  id: number;
  content: string;
  points: number;
  description: string;
  startDate: string;
  endDate: string;
  time: string;
  selectedClasses: string[];
  type: 'type1' | 'type2' | 'type3' | 'type4' | 'type5';
}

// 新任务表单类型定义
interface NewTaskForm {
  content: string;
  points: string | number;
  description: string;
  startDate: string;
  endDate: string;
  time: string;
  selectedClasses: string[];
  type: 'type1' | 'type2' | 'type3' | 'type4' | 'type5';
}

// 错误信息类型定义
interface FormErrors {
  title: string;
  points: string;
  description: string;
  startDate: string;
  endDate: string;
  students: string;
}

// 树形结构节点类型
interface TreeNode {
  key: string;
  title: string;
  children?: TreeNode[];
  value?: string;
  isLeaf?: boolean;
}

// 日历日期类型
interface CalendarDay {
  date: number;
  fullDate: string;
  isCurrentMonth: boolean;
  isCurrentDay: boolean;
  dayOfWeek: number;
}

// 用户信息类型
interface UserInfo {
  id: number;
  [key: string]: any;
}

// API响应类型
interface ApiResponse<T = any> {
  code: number;
  msg?: string;
  data?: T;
}

// 任务列表API响应数据类型
interface TaskListResponseData {
  list: Array<{
    id: number;
    title: string;
    score: number;
    desc: string;
    start_time: string;
    end_time: string;
    student_ids: string[];
  }>;
}

// 学生列表API响应数据类型
interface StudentListResponseData {
  list: Array<{
    id: number;
    title: string;
    nickname: string;
  }>;
}

const CalendarTask = () => {
  const [currentDate, setCurrentDate] = useState<Dayjs>(dayjs());
  const [taskDialogVisible, setTaskDialogVisible] = useState<boolean>(false);
  const [selectedDate, setSelectedDate] = useState<CalendarDay | null>(null);
  const [isSubmitting, setIsSubmitting] = useState<boolean>(false);
  const [editingTaskId, setEditingTaskId] = useState<number | null>(null);
  const [loading, setLoading] = useState<boolean>(false);
  const [expandedKeys, setExpandedKeys] = useState<string[]>([]);
  const [autoExpandParent, setAutoExpandParent] = useState<boolean>(true);

  const [errors, setErrors] = useState<FormErrors>({
    title: '',
    points: '',
    description: '',
    startDate: '',
    endDate: '',
    students: ''
  });

  const [newTask, setNewTask] = useState<NewTaskForm>({
    content: '',
    points: '',
    description: '',
    startDate: dayjs().format('YYYY-MM-DD HH:mm'),
    endDate: dayjs().add(1, 'hour').format('YYYY-MM-DD HH:mm'),
    time: '08:00',
    selectedClasses: [],
    type: 'type1'
  });

  const [tasks, setTasks] = useState<Task[]>([]);
  const [treeData, setTreeData] = useState<TreeNode[]>([]);
  const [selectedTreeKeys, setSelectedTreeKeys] = useState<string[]>([]);

  // 全部展开/收起功能
  const expandAll = () => {
    const allKeys = treeData.map(classNode => classNode.key);
    setExpandedKeys(allKeys);
    setAutoExpandParent(true);
  };

  const collapseAll = () => {
    setExpandedKeys([]);
    setAutoExpandParent(false);
  };

  // 树节点展开时
  const onExpand: TreeProps['onExpand'] = (expandedKeysValue) => {
    setExpandedKeys(expandedKeysValue as string[]);
    setAutoExpandParent(false);
  };

  // 获取用户信息
  const getUserInfo = (): UserInfo | null => {
    try {
      const storedUserInfo = localStorage.getItem('userInfo');
      if (storedUserInfo) {
        return JSON.parse(storedUserInfo);
      }
      return null;
    } catch (error) {
      console.error('获取用户信息失败:', error);
      return null;
    }
  };

  // 获取任务数据
  const fetchTaskData = async () => {
    try {
      const userInfo = getUserInfo();
      if (!userInfo) {
        message.warning('请先登录');
        return;
      }

      setLoading(true);
      const res: ApiResponse<TaskListResponseData> = await task_list({
        userId: userInfo.id,
        role: 1
      });

      if (res.code === 1 && res.data) {
        const formattedTasks: Task[] = res.data.list.map((item, index) => {
          const startTime = item.start_time || '';
          const endTime = item.end_time || '';
          const timePart = startTime.split(' ')[1] || '';
          const timeStr = timePart ? timePart.slice(0, 5) : '08:00';
          const typeIndex = (index % 5) + 1;

          return {
            id: item.id,
            content: item.title,
            points: item.score,
            description: item.desc,
            startDate: startTime,
            endDate: endTime,
            time: timeStr,
            selectedClasses: item.student_ids || [],
            type: `type${typeIndex}` as 'type1' | 'type2' | 'type3' | 'type4' | 'type5'
          };
        });
        setTasks(formattedTasks);
      } else {
        message.error(res.msg || '数据加载失败');
      }
    } catch (error) {
      console.error('获取任务数据失败:', error);
      message.error('数据加载失败');
    } finally {
      setLoading(false);
    }
  };

  // 获取学生数据并构建树形结构
  const fetchStudentData = async () => {
    try {
      const userInfo = getUserInfo();
      if (!userInfo) {
        message.warning('请先登录');
        return;
      }

      const res: ApiResponse<StudentListResponseData> = await studentList({
        squad_id_: '',
        role: 1
      });

      if (res.code === 1 && res.data) {
        // 按班级分组学生
        const classesMap: Record<string, TreeNode> = {};

        res.data.list.forEach(student => {
          const className = student.title || '未分组'; // 使用 title 字段作为班级名称
          if (!classesMap[className]) {
            classesMap[className] = {
              key: `class-${className}`,
              title: className,
              children: []
            };
          }

          classesMap[className].children!.push({
            key: student.id.toString(),
            title: student.nickname,
            value: student.id.toString(),
            isLeaf: true
          });
        });

        // 转换为树形结构数据
        const treeData = Object.values(classesMap);
        setTreeData(treeData);
      } else {
        message.error(res.msg || '学生数据加载失败');
      }
    } catch (error) {
      console.error('获取学生数据失败:', error);
      message.error('学生数据加载失败');
    }
  };

  // 在获取学生数据后，默认展开所有节点
  useEffect(() => {
    if (treeData.length > 0) {
      expandAll();
    }
  }, [treeData]);

  // 渲染模态框的表单部分
  const renderForm = () => (
    <div className="dialog-body">
      <div className="form-section">
        <div className="form-item">
          <div className="form-content">
            <label className="form-label">任务标题</label>
            <Input
              placeholder="请输入任务标题"
              value={newTask.content}
              className='width80'
              onChange={(e) => setNewTask(prev => ({ ...prev, content: e.target.value }))}
              onBlur={() => validateField('title')}
              status={errors.title ? 'error' : ''}
            />
          </div>
          {errors.title && <div className="error-message">{errors.title}</div>}
        </div>
      </div>

      <div className="form-section">
        <div className="form-item">
          <div className="form-content">
            <label className="form-label">任务介绍</label>
            <Input
              className='width80'
              placeholder="请输入任务介绍"
              value={newTask.description}
              onChange={(e) => setNewTask(prev => ({ ...prev, description: e.target.value }))}
              onBlur={() => validateField('description')}
              status={errors.description ? 'error' : ''}
            />
          </div>
          {errors.description && <div className="error-message">{errors.description}</div>}
        </div>
      </div>

      <div className="form-section">
        <div className="form-item">
          <div className="form-content">
            <label className="form-label">积分奖励</label>
            <InputNumber
              className='width80'
              placeholder="请输入积分奖励"
              min={1}
              value={newTask.points}
              onChange={(value) => {
                setNewTask(prev => ({ ...prev, points: value }));

                // 实时校验：输入负分时立即显示错误
                if (value !== null && value <= 0) {
                  setErrors(prev => ({ ...prev, points: '请输入有效的积分奖励' }));
                } else if (value !== null && value > 0) {
                  setErrors(prev => ({ ...prev, points: '' }));
                }
              }}
              onBlur={() => validateField('points')}
              status={errors.points ? 'error' : ''}
            />
          </div>
          {errors.points && <div className="error-message">{errors.points}</div>}
        </div>
      </div>

      <div className="form-section">
        <div className="form-item">
          <div className="form-content">
            <label className="form-label">开始时间</label>
            <DatePicker
              showTime
              className='width80'
              format="YYYY-MM-DD HH:mm"
              value={newTask.startDate ? dayjs(newTask.startDate) : null}
              onChange={(date) => {
                const formattedDate = date ? date.format('YYYY-MM-DD HH:mm') : '';
                setNewTask(prev => ({
                  ...prev,
                  startDate: formattedDate
                }));

                // 立即清除错误信息并验证
                setErrors(prev => ({ ...prev, startDate: '' }));

                // 如果结束时间存在且早于新的开始时间，也清除结束时间错误
                if (newTask.endDate && date && dayjs(newTask.endDate).isBefore(date)) {
                  setErrors(prev => ({ ...prev, endDate: '' }));
                }
              }}
              disabledDate={disablePastDates}
              status={errors.startDate ? 'error' : ''}
            />
          </div>
          {errors.startDate && <div className="error-message">{errors.startDate}</div>}
        </div>
      </div>

      <div className="form-section">
        <div className="form-item">
          <div className="form-content">
            <label className="form-label">结束时间</label>
            <DatePicker
              showTime
              className='width80'
              format="YYYY-MM-DD HH:mm"
              value={newTask.endDate ? dayjs(newTask.endDate) : null}
              onChange={(date) => {
                const formattedDate = date ? date.format('YYYY-MM-DD HH:mm') : '';
                setNewTask(prev => ({
                  ...prev,
                  endDate: formattedDate
                }));

                // 立即清除错误信息
                setErrors(prev => ({ ...prev, endDate: '' }));
              }}
              disabledDate={(current) => {
                // 结束时间不能早于开始时间
                if (newTask.startDate) {
                  return current && current < dayjs(newTask.startDate);
                }
                return current && current < dayjs().startOf('day');
              }}
              status={errors.endDate ? 'error' : ''}
            />
          </div>
          {errors.endDate && <div className="error-message">{errors.endDate}</div>}
        </div>
      </div>

      <div className="form-section">
        <div className="form-item">
          <div className="formcontent">
            <div className="tree-actions">
              <label className="form-label" style={{ marginLeft: '28px' }}>学生</label>
              <Button
                size="small"
                icon={<DownOutlined />}
                onClick={expandAll}
                style={{ marginRight: 8 }}
              >
                全部展开
              </Button>
              <Button
                size="small"
                icon={<UpOutlined />}
                onClick={collapseAll}
              >
                全部收起
              </Button>
            </div>
            <Tree
              treeData={treeData}
              checkable
              checkedKeys={selectedTreeKeys}
              onCheck={handleTreeCheck}
              expandedKeys={expandedKeys}
              autoExpandParent={autoExpandParent}
              onExpand={onExpand}
              height={200}
              style={{ marginTop: 8, width: '70%', margin: 'auto' }}
            />
          </div>
          {errors.students && <div className="error-message">{errors.students}</div>}
        </div>
      </div>
    </div>
  );

  useEffect(() => {
    fetchTaskData();
    fetchStudentData();
  }, []);

  // 生成日历周数据
  const calendarWeeks = useCallback((): CalendarDay[][] => {
    const startOfMonth = currentDate.startOf('month');
    const startDay = startOfMonth.day() || 7;
    const calendarStart = startOfMonth.subtract(startDay - 1, 'day');

    const weeksArray: CalendarDay[][] = [];
    let currentWeek: CalendarDay[] = [];

    for (let i = 0; i < 42; i++) {
      const day = calendarStart.add(i, 'day');
      const isCurrentMonth = day.month() === currentDate.month();
      const isCurrentDay = day.isSame(dayjs(), 'day');

      currentWeek.push({
        date: day.date(),
        fullDate: day.format('YYYY-MM-DD'),
        isCurrentMonth,
        isCurrentDay,
        dayOfWeek: day.day()
      });

      if ((i + 1) % 7 === 0) {
        weeksArray.push(currentWeek);
        currentWeek = [];
      }
    }

    return weeksArray;
  }, [currentDate]);

  // 获取指定日期的任务
  const getTasksForDate = (date: string): Task[] => {
    return tasks.filter(task => {
      const taskStartDate = task.startDate.split(' ')[0];
      const taskEndDate = task.endDate.split(' ')[0];
      return date >= taskStartDate && date <= taskEndDate;
    });
  };

  // 获取任务颜色类名
  const getTaskColorClass = (task: Task, index: number): string => {
    if (task.type && ['type1', 'type2', 'type3', 'type4', 'type5'].includes(task.type)) {
      return `event-${task.type}`;
    }
    const colorIndex = index % 5 + 1;
    return `event-type${colorIndex}`;
  };

  // 表单验证字段类型
  type Field = 'title' | 'points' | 'description' | 'startDate' | 'endDate' | 'students';

  // 表单验证
  const validateField = (field: Field): boolean => {
    let isValid = true;

    switch (field) {
      case 'title':
        if (!newTask.content?.trim()) {
          setErrors(prev => ({ ...prev, title: '任务标题不能为空' }));
          isValid = false;
        } else {
          setErrors(prev => ({ ...prev, title: '' }));
        }
        break;

      case 'points':
        if (!newTask.points || Number(newTask.points) <= 0) {
          setErrors(prev => ({ ...prev, points: '请输入有效的积分奖励' }));
          isValid = false;
        } else {
          setErrors(prev => ({ ...prev, points: '' }));
        }
        break;

      case 'description':
        if (!newTask.description?.trim()) {
          setErrors(prev => ({ ...prev, description: '任务介绍不能为空' }));
          isValid = false;
        } else {
          setErrors(prev => ({ ...prev, description: '' }));
        }
        break;

      case 'startDate':
        if (!newTask.startDate) {
          setErrors(prev => ({ ...prev, startDate: '请选择开始时间' }));
          isValid = false;
        } else if (dayjs(newTask.startDate).isBefore(dayjs())) {
          setErrors(prev => ({ ...prev, startDate: '开始时间不能早于当前时间' }));
          isValid = false;
        } else {
          setErrors(prev => ({ ...prev, startDate: '' }));
        }
        break;

      case 'endDate':
        if (!newTask.endDate) {
          setErrors(prev => ({ ...prev, endDate: '请选择结束时间' }));
          isValid = false;
        } else if (dayjs(newTask.endDate).isBefore(dayjs())) {
          setErrors(prev => ({ ...prev, endDate: '结束时间不能早于当前时间' }));
          isValid = false;
        } else if (newTask.startDate && dayjs(newTask.endDate).isBefore(dayjs(newTask.startDate))) {
          setErrors(prev => ({ ...prev, endDate: '结束时间不能早于开始时间' }));
          isValid = false;
        } else {
          setErrors(prev => ({ ...prev, endDate: '' }));
        }
        break;

      case 'students':
        if (selectedTreeKeys.length === 0) {
          setErrors(prev => ({ ...prev, students: '请至少选择一名学生' }));
          isValid = false;
        } else {
          setErrors(prev => ({ ...prev, students: '' }));
        }
        break;
    }

    return isValid;
  };

  const validateForm = (): boolean => {
    const fields: Field[] = ['title', 'points', 'description', 'startDate', 'endDate', 'students'];
    let isValid = true;

    fields.forEach(field => {
      if (!validateField(field)) {
        isValid = false;
      }
    });

    return isValid;
  };

  // 打开任务对话框
  const openTaskDialog = (day: CalendarDay) => {
    if (day && dayjs(day.fullDate).isBefore(dayjs().startOf('day'))) {
      message.warning('只能添加今天及以后的打卡任务');
      return;
    }

    setSelectedDate(day);
    setEditingTaskId(null);
    setSelectedTreeKeys([]);
    setErrors({
      title: '',
      points: '',
      description: '',
      startDate: '',
      endDate: '',
      students: ''
    });

    if (day) {
      setNewTask(prev => ({
        ...prev,
        startDate: '',
        endDate: ''
      }));
    } else {
      setNewTask(prev => ({
        ...prev,
        startDate: dayjs().format('YYYY-MM-DD HH:mm'),
        endDate: dayjs().add(1, 'hour').format('YYYY-MM-DD HH:mm')
      }));
    }

    setTaskDialogVisible(true);
  };

  // 打开编辑对话框
  const openEditDialog = (task: Task) => {
    console.log(task);

    if (dayjs(task.startDate).isBefore(dayjs().startOf('day'))) {
      message.warning('不能编辑过去的打卡任务');
      return;
    }

    setTaskDialogVisible(true);
    setEditingTaskId(task.id);
    setSelectedDate({
      fullDate: task.startDate.split(' ')[0],
      date: Number(task.startDate.split(' ')[0].split('-')[2]),
      isCurrentDay: false,
      isCurrentMonth: false,
      dayOfWeek: 0
    });

    setNewTask({
      content: task.content,
      points: task.points.toString(),
      description: task.description,
      startDate: task.startDate,
      endDate: task.endDate,
      time: task.time,
      selectedClasses: task.selectedClasses,
      type: task.type
    });

    setSelectedTreeKeys(task.selectedClasses.map(id => id.toString()));
    setErrors({
      title: '',
      points: '',
      description: '',
      startDate: '',
      endDate: '',
      students: ''
    });
  };

  // 关闭对话框
  const closeTaskDialog = () => {
    setTaskDialogVisible(false);
    setNewTask({
      content: '',
      points: '',
      description: '',
      startDate: dayjs().format('YYYY-MM-DD HH:mm'),
      endDate: dayjs().add(1, 'hour').format('YYYY-MM-DD HH:mm'),
      time: '08:00',
      selectedClasses: [],
      type: 'type1'
    });
    setSelectedTreeKeys([]);
    setEditingTaskId(null);
  };

  // 处理树形选择 - 修改为只选择学生节点
  const handleTreeCheck: TreeProps['onCheck'] = (checkedKeys, { checkedNodes }) => {
    // 只选择学生节点（叶子节点），过滤掉班级节点
    const studentKeys = checkedNodes
      .filter(node => node.isLeaf)
      .map(node => node.key);

    setSelectedTreeKeys(studentKeys);

    // 选择学生后立即清除错误信息
    if (studentKeys.length > 0) {
      setErrors(prev => ({ ...prev, students: '' }));
    } else {
      validateField('students');
    }
  };

  // 添加/编辑任务
  const handleAddTask = async () => {
    // 先进行表单验证
    const isValid = validateForm();

    if (!isValid) {
      message.error('请完善表单信息');
      return;
    }

    const userInfo = getUserInfo();
    if (!userInfo) {
      message.warning('请先登录');
      return;
    }

    const requestData = {
      ...(editingTaskId && { id: editingTaskId }),
      title: newTask.content,
      desc: newTask.description,
      score: newTask.points.toString(),
      start_time: dayjs(newTask.startDate).format('YYYY-MM-DD HH:mm:ss'),
      end_time: dayjs(newTask.endDate).format('YYYY-MM-DD HH:mm:ss'),
      user_id: userInfo.id.toString(),
      student_id: selectedTreeKeys.join(',')
    };

    try {
      setIsSubmitting(true);
      const res: ApiResponse = await task_add(requestData);

      if (res.code === 1) {
        message.success(editingTaskId ? '任务更新成功' : '任务添加成功');

        if (editingTaskId) {
          setTasks(prev => prev.map(task =>
            task.id === editingTaskId ? {
              ...task,
              content: newTask.content,
              points: parseInt(newTask.points as string) || 0,
              description: newTask.description,
              startDate: newTask.startDate,
              endDate: newTask.endDate,
              time: newTask.startDate.split(' ')[1]?.slice(0, 5) || '08:00',
              selectedClasses: selectedTreeKeys,
              type: newTask.type
            } : task
          ));
        } else {
          const newId = tasks.length > 0 ? Math.max(...tasks.map(t => t.id)) + 1 : 1;
          setTasks(prev => [...prev, {
            id: newId,
            content: newTask.content,
            points: parseInt(newTask.points as string) || 0,
            description: newTask.description,
            startDate: newTask.startDate,
            endDate: newTask.endDate,
            time: newTask.startDate.split(' ')[1]?.slice(0, 5) || '08:00',
            selectedClasses: selectedTreeKeys,
            type: newTask.type
          }]);
        }

        closeTaskDialog();
      } else {
        message.error(res.msg || (editingTaskId ? '任务更新失败' : '任务添加失败'));
      }
    } catch (error) {
      console.error('操作失败:', error);
      message.error('网络错误，操作失败');
    } finally {
      setIsSubmitting(false);
    }
  };

  // 月份导航
  const prevMonth = () => setCurrentDate(prev => prev.subtract(1, 'month'));
  const nextMonth = () => setCurrentDate(prev => prev.add(1, 'month'));
  const goToday = () => setCurrentDate(dayjs());

  // 格式化对话框日期
  const formatDialogDate = (date: string) => dayjs(date).format('YYYY年MM月DD日');

  // 禁止选择过去的日期
  const disablePastDates = (current: Dayjs | null) => current && current < dayjs().startOf('day');

  const currentMonth = currentDate.format('YYYY年M月');
  const weeks = calendarWeeks();

  return (
    <div className="container">
      <h3>打卡任务</h3>

      <div className="calendar-container">
        <div className="calendar-header">
          <div className="calendar-nav">
            <button onClick={prevMonth}>
              <LeftOutlined />
            </button>
          </div>
          <div className="calendar-title">{currentMonth}</div>
          <div className="calendar-nav">
            <span onClick={goToday}>今天</span>
            <button onClick={nextMonth}>
              <RightOutlined />
            </button>
          </div>
        </div>

        <div className="calendar-grid">
          <div className="week-header">
            <div className="week-header-cell">周一</div>
            <div className="week-header-cell">周二</div>
            <div className="week-header-cell">周三</div>
            <div className="week-header-cell">周四</div>
            <div className="week-header-cell">周五</div>
            <div className="week-header-cell">周六</div>
            <div className="week-header-cell">周日</div>
          </div>

          {weeks.map((week, weekIndex) => (
            <div key={weekIndex} className="calendar-week">
              {week.map((day, dayIndex) => (
                <div
                  key={dayIndex}
                  className={`calendar-day ${day.isCurrentDay ? 'current-day' : ''} ${!day.isCurrentMonth ? 'other-month' : ''}`}
                  onClick={() => openTaskDialog(day)}
                >
                  <div className="day-header">
                    <div className="day-date">{day.date}日</div>
                  </div>

                  <div className="event-list">
                    {getTasksForDate(day.fullDate).map((task, taskIndex) => (
                      <div
                        key={taskIndex}
                        className={`event-item ${getTaskColorClass(task, taskIndex)}`}
                        onClick={(e) => {
                          e.stopPropagation();
                          openEditDialog(task);
                        }}
                      >
                        {day.fullDate === dayjs(task.startDate).format('YYYY-MM-DD') && (
                          <>
                            <span className="event-time">{task.time}</span>
                            <span className="event-content">{task.content}</span>
                          </>
                        )}
                      </div>
                    ))}
                  </div>
                </div>
              ))}
            </div>
          ))}
        </div>
      </div>

      <Modal
        title={editingTaskId ? '编辑任务' : (selectedDate ? `在 ${formatDialogDate(selectedDate.fullDate)} 添加任务` : '添加打卡任务')}
        open={taskDialogVisible}
        onCancel={closeTaskDialog}
        footer={[
          <Button key="cancel" onClick={closeTaskDialog}>取消</Button>,
          <Button
            key="submit"
            type="primary"
            loading={isSubmitting}
            onClick={handleAddTask}
          >
            {isSubmitting ? (editingTaskId ? '更新中...' : '提交中...') : '确定'}
          </Button>
        ]}
        width={600}
        className="task-dialog"
      >
        {renderForm()}
      </Modal>

      {loading && (
        <div className="loading-overlay">
          <Spin size="large" />
        </div>
      )}
    </div>
  );
};

export default CalendarTask;
